﻿#region

using System.ComponentModel.DataAnnotations;
using Vin.Extension.Framework.Dto;
using Vin.Extension.Framework.Models;

#endregion

namespace Vin.Extension.Framework.Attributes.Validation;

public class FromAuthorizeAttribute(string? propertyName = null, string? tokenModelName = null) : ValidationAttribute
{
    public string? UnauthorizedMessage { get; set; } = "未授权";

    public string? PropertyName { get; set; } = propertyName;

    public string? TokenModelName { get; set; } = tokenModelName ?? propertyName;

    public string? TokenPrefix { get; set; }

    public bool IsRequired { get; set; }

    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
    {
        var tokenModel = VinTokenModelTool.GetTokenModel(TokenPrefix);
        if (tokenModel == null)
        {
            return new ValidationResult(UnauthorizedMessage);
        }

        var displayObj = validationContext.ObjectType.GetProperty(PropertyName ?? validationContext.DisplayName);
        var displayValue = tokenModel.GetType().GetProperty(PropertyName ?? validationContext.DisplayName)
            ?.GetValue(tokenModel);
        displayObj?.SetValue(validationContext.ObjectInstance, displayValue);

        if (IsRequired && displayValue == null)
        {
            return new ValidationResult(ErrorMessage);
        }

        return ValidationResult.Success;
    }

    public string? GetValueFromAuthorize()
    {
        var tokenModel = VinTokenModelTool.GetTokenModel(TokenPrefix);
        if (tokenModel == null) return null;
        return tokenModel.GetType().GetProperty(TokenModelName ?? "")?.GetValue(tokenModel)?.ToString();
    }
}